using System.Diagnostics;
using Headspring.Training.Domain.Model;
using Headspring.Training.Domain.Model.StateCommands;
using Headspring.Training.Domain.Services;
using Headspring.Training.Domain.Services.Impl;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;

namespace Headspring.Training.Domain.UnitTests.Services
{
    [TestFixture]
    public class WorkflowFacilitatorTester
    {
        [Test]
        public void ShouldGetNoValidStateCommandsForWrongUser()
        {
            WorkflowFacilitator facilitator = new WorkflowFacilitator();
            IStateCommand[] commands = facilitator.GetValidStateCommands(new WorkOrder(), new Employee());

            Assert.That(commands.Length, Is.EqualTo(0));
        }

        
        [Test]
        public void ShouldReturnAllStateCommandsInCorrectOrder()
        {
            WorkflowFacilitator facilitator = new WorkflowFacilitator();
            IStateCommand[] commands = facilitator.GetAllStateCommands(new WorkOrder(), new Employee());

            Assert.That(commands.Length, Is.EqualTo(8));
            Assert.That(commands[0], Is.InstanceOfType(typeof (SaveDraftCommand)));
            Assert.That(commands[1], Is.InstanceOfType(typeof (DraftToAssignedCommand)));
            Assert.That(commands[2], Is.InstanceOfType(typeof (AssignedToInProgressCommand)));
            Assert.That(commands[3], Is.InstanceOfType(typeof (InProgressToCompleteCommand)));
            Assert.That(commands[4], Is.InstanceOfType(typeof (DraftToCancelledCommand)));
            Assert.That(commands[5], Is.InstanceOfType(typeof (AssignedToCancelledCommand)));
            Assert.That(commands[6], Is.InstanceOfType(typeof (InProgressToCancelledCommand)));
            Assert.That(commands[7], Is.InstanceOfType(typeof (CompleteToAssignedCommand)));
        }

        [Test]
        public void ShouldFilterFullListToReturnValidCommands()
        {
            MockRepository mocks = new MockRepository();
            WorkflowFacilitator facilitator = mocks.PartialMock<WorkflowFacilitator>();
            IStateCommand[] commandsToReturn = new IStateCommand[]
                {
                    new StubbedStateCommand(true), new StubbedStateCommand(true), 
                    new StubbedStateCommand(false)
                };

            Expect.Call(facilitator.GetAllStateCommands(null, null)).IgnoreArguments().Return(commandsToReturn);
            mocks.ReplayAll();

            IStateCommand[] commands = facilitator.GetValidStateCommands(null, null);

            mocks.VerifyAll();
            Assert.That(commands.Length, Is.EqualTo(2));
        }

        public class StubbedStateCommand : IStateCommand
        {
            private bool _isValid;

            public StubbedStateCommand(bool isValid)
            {
                _isValid = isValid;
            }

            public bool IsValid()
            {
                return _isValid;
            }

            public void Execute(IWorkflowCoordinator coordinator)
            {
                throw new System.NotImplementedException();
            }

            public string TransitionVerbPresentTense
            {
                get { throw new System.NotImplementedException(); }
            }

            public bool Matches(string commandName)
            {
                throw new System.NotImplementedException();
            }

          public WorkOrderStatus GetBeginStatus()
          {
            throw new System.NotImplementedException();
          }
        }
    }
}